﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Interface;
using Model;

namespace Controller
{
    public class MyController
    {
        DBFacade dbFacade;
        List<IProduct> iProduct;
        List<IBrand> iBrand;
        List<ICategory> iCategory;
        List<IProductDetail> iProductDetails;
        ProductCol productCol;
        BrandCol brandCol;
        CategoryCol categoryCol;
        ProductDetailCol productDetailCol;
        IProduct currentProduct;
        IProductDetail currentProductDetail;
        SalesOrganization salesOrganization;
        SalesOrganizationCol salesOrganizationCol;

        #region Session variables
        public int SortBy { get; set; }
        public int ProductsPerPage { get; set; }
        public int GridSize { get; set; }
        public decimal CurrentPrice { get; set; }
        #endregion

        public MyController()
        {
            productCol = new ProductCol();
            brandCol = new BrandCol();
            categoryCol = new CategoryCol();
            productDetailCol = new ProductDetailCol();
            salesOrganizationCol = new SalesOrganizationCol();
            dbFacade = new DBFacade(productCol, brandCol, categoryCol, productDetailCol, salesOrganizationCol);

            // Indlæs data
            dbFacade.LoadData();

            //set sessions
            SortBy = 0;
            GridSize = 3;
            ProductsPerPage = GridSize * GridSize;
            CurrentPrice = GetMaxPrice();
            iProduct = GetProducts();
        }

        // Normal søgnings
        public int Search(string query)
        {
            this.iProduct.Clear();

            if (string.IsNullOrEmpty(query) || query == "Søgeord")
                foreach (Product product in this.productCol.GetProductListe())
                    this.iProduct.Add(product);
            else
            {
                foreach (Product product in this.productCol.GetProductListe())
                {
                    if (product.Name == query)
                        this.iProduct.Add(product);
                    if (product.Id.ToString().Contains(query))
                        this.iProduct.Add(product);
                }
            }
            return this.iProduct.Count();
        }

        // Adv søgning
        public int AdvSearch(string query, decimal maxPrice, ICategory category, IBrand brand)
        {
            this.iProduct.Clear();

            var q = from p in productCol.GetProductListe()
                    join c in categoryCol.CategoryList on p.Category equals c
                    join b in brandCol.BrandList on p.Brand equals b
                    where p.Id.ToString().Contains(query) ||
                          b == brand ||
                          c == category ||
                          p.Price == maxPrice
                    orderby p.Id
                    select new { p.Id, b, c, p.Price, p.AvailabilityLevel, p.Status, p.ProductDetails, p.LaunchDate };

            foreach (var x in q)
            {
                iProduct.Add(new Product(x.Id, x.Status, x.LaunchDate, x.AvailabilityLevel, x.Price, x.c, x.b));
                // Console.WriteLine("Id: {0}\nBrandName: {1}\nCategory: {2}\nPrice: {3}\n\n", x.Id, x.b.BrandName, x.c.Description, x.Price);
            }

            return this.iProduct.Count();
        }

        #region Get Methods
        #region Price
        public decimal GetMinPrice()
        {
            return productCol.GetProductListe().Min(p => p.Price);
        }

        public decimal GetMaxPrice()
        {
            return productCol.GetProductListe().Max(p => p.Price);
        }
        #endregion

        #region Interface Lists
        public List<IProduct> GetProducts()//der skal være en form for query der kan afgrænse mængden af data
        {//en temp liste til resultater af sin søgning

            if (iProduct == null)
            {
                iProduct = new List<IProduct>();
                foreach (Product p in productCol.GetProductListe())
                    iProduct.Add(p);
            }

            if (CurrentPrice != GetMaxPrice())
            {
                foreach (Product p in productCol.GetProductListe())
                {
                    if (p.Price <= CurrentPrice)
                    {
                        iProduct.Add((IProduct)p);
                    }
                }
            }

            #region SortBy
            switch (SortBy)
            {
                case 1: //dato
                    iProduct = iProduct.OrderByDescending(p => p.LaunchDate).ToList();
                    break;
                case 2: //produktnavn
                    iProduct = iProduct.OrderBy(p => p.Name).ToList();
                    break;
                case 3: //pris lav -> høj
                    iProduct = iProduct.OrderBy(p => p.Price).ToList();
                    break;
                case 4: //pris høj -> lav
                    iProduct = iProduct.OrderByDescending(p => p.Price).ToList();
                    break;
                default: //produktid
                    iProduct = iProduct.OrderBy(p => p.Id).ToList();
                    break;
            }
            #endregion
            return iProduct;
        }
        public List<IBrand> GetBrands()
        {
            if (iBrand == null)
            {
                iBrand = new List<IBrand>();
                foreach (Brand b in brandCol.BrandList)
                    iBrand.Add(b);
            }
            return iBrand;
        }
        public List<ICategory> GetCategories()
        {
            if (iCategory == null)
            {
                iCategory = new List<ICategory>();
                foreach (Category c in categoryCol.CategoryList)
                    iCategory.Add(c);
            }
            return iCategory;
        }
        public List<IProductDetail> GetProductDetails()
        {
            if (iProductDetails == null)
            {
                iProductDetails = new List<IProductDetail>();
                foreach (ProductDetail pd in productDetailCol.ProductDetailList)
                    iProductDetails.Add(pd);
            }
            return iProductDetails;
        }
        #endregion


        public IProductDetail FindProductDetail(int id)
        {
            currentProduct = FindProduct(id);
            foreach (ProductDetail pd in GetProductDetails())
            {
                if (pd.Product == currentProduct)
                {
                    currentProductDetail = pd;
                    break;
                }
            }

            return currentProductDetail;
        }

        public IProduct FindProduct(int id)
        {
            foreach (IProduct p in iProduct)
            {
                if (p.Id == id)
                {
                    currentProduct = p;
                    break;
                }
            }

            return currentProduct;
        }

        public int GetMaxPageNumber()
        {
            double left = iProduct.Count() % ProductsPerPage;
            int pages = iProduct.Count() / ProductsPerPage;
            if (left > 0)
                pages += 1;
            return pages;
        }
        #endregion

        #region ProductSortBy
        //liste til sortering, valgmuligheder
        List<string> ProductSortBy = new List<string>(){
            "Produktid", "Lanceringsdato", "Produktnavn", "Pris (lav til høj)", "Pris (høj til lav)"
        };
        public List<string> GetProductSortBy()
        {
            return ProductSortBy;
        }
        #endregion
    }
}
